﻿// ------------------------------------------------------------------------
// 项目名称：Canroc.Net 
// 版权归属：Canroc（https://gitee.com/canroc）
//
// 许可证信息
// Canroc.Net项目主要遵循 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-APACHE 文件。
//
// 使用条款：
// 1.使用本项目应遵守相关法律法规和许可证的要求。
// 2.不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动。
// 3.任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任
//
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
//
// 其他重要信息
// Canroc.Net 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// ------------------------------------------------------------------------

namespace Canroc.Net.Core.Extension;

/// <summary>
///     值类型转换扩展
/// </summary>
public static class TypeParseExtension
{
    #region 转换为Guid

    /// <summary>
    ///     将object转换为Guid，若转换失败，则返回Guid.Empty。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static Guid ParseToGuid(this object obj)
    {
        try
        {
            return Guid.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return Guid.Empty;
        }
    }

    #endregion

    #region 转换为string

    /// <summary>
    ///     将object转换为string，若转换失败，则返回""。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static string ParseToString(this object obj)
    {
        try
        {
            return obj.ToString() ?? string.Empty;
        }
        catch
        {
            return string.Empty;
        }
    }

    #endregion

    #region 转换为 char

    /// <summary>
    ///     将object转换为char，若转换失败，则返回' '。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static char ParseToToChar(this object obj)
    {
        try
        {
            return Convert.ToChar(obj);
        }
        catch
        {
            return ' ';
        }
    }

    #endregion

    #region 强制转换类型

    /// <summary>
    ///     强制转换类型
    /// </summary>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="source"></param>
    /// <returns></returns>
    public static IEnumerable<TResult> CastSuper<TResult>(this IEnumerable source)
    {
        return from object item in source select (TResult)Convert.ChangeType(item, typeof(TResult));
    }

    #endregion

    #region 转换为long

    /// <summary>
    ///     将object转换为long，若转换失败，则返回0。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static long ParseToLong(this object obj)
    {
        try
        {
            return long.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return 0L;
        }
    }

    /// <summary>
    ///     将object转换为long，若转换失败，则返回指定值。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static long ParseToLong(this string obj, long defaultValue)
    {
        try
        {
            return long.Parse(obj);
        }
        catch
        {
            return defaultValue;
        }
    }

    #endregion

    #region 转换为int

    /// <summary>
    ///     将object转换为int，若转换失败，则返回0。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static int ParseToInt(this object obj)
    {
        try
        {
            return Convert.ToInt32(obj);
        }
        catch
        {
            return 0;
        }
    }

    /// <summary>
    ///     将object转换为int，若转换失败，则返回指定值。不抛出异常。
    ///     null返回默认值
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static int ParseToInt(this object obj, int defaultValue)
    {
        try
        {
            return Convert.ToInt32(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return defaultValue;
        }
    }

    #endregion

    #region 转换为short

    /// <summary>
    ///     将object转换为short，若转换失败，则返回0。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static short ParseToShort(this object obj)
    {
        try
        {
            return short.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return 0;
        }
    }

    /// <summary>
    ///     将object转换为short，若转换失败，则返回指定值。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static short ParseToShort(this object obj, short defaultValue)
    {
        try
        {
            return short.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return defaultValue;
        }
    }

    #endregion

    #region 转换为demical

    /// <summary>
    ///     将object转换为decimal，若转换失败，则返回指定值。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static decimal ParseToDecimal(this object obj, decimal defaultValue)
    {
        try
        {
            return decimal.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary>
    ///     将object转换为decimal，若转换失败，则返回0。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static decimal ParseToDecimal(this object obj)
    {
        try
        {
            return decimal.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return 0;
        }
    }

    #endregion

    #region 转换为double

    /// <summary>
    ///     将object转换为double，若转换失败，则返回0。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static double ParseToDouble(this object obj)
    {
        try
        {
            return double.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return 0;
        }
    }

    /// <summary>
    ///     将object转换为double，若转换失败，则返回指定值。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static double ParseToDouble(this object obj, double defaultValue)
    {
        try
        {
            return double.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return defaultValue;
        }
    }

    #endregion

    #region 转换为float

    /// <summary>
    ///     将object转换为float，若转换失败，则返回0。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static float ParseToFloat(this object obj)
    {
        try
        {
            return float.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return 0;
        }
    }

    /// <summary>
    ///     将object转换为float，若转换失败，则返回指定值。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public static float ParseToFloat(this object obj, float result)
    {
        try
        {
            return float.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return result;
        }
    }

    #endregion

    #region 转化为bool

    /// <summary>
    ///     将object转换为bool，若转换失败，则返回false。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool ParseToBool(this object obj)
    {
        try
        {
            return bool.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    ///     将object转换为bool，若转换失败，则返回指定值。不抛出异常。
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public static bool ParseToBool(this object obj, bool result)
    {
        try
        {
            return bool.Parse(obj.ToString() ?? string.Empty);
        }
        catch
        {
            return result;
        }
    }

    #endregion

    #region 转换为DateTime

    /// <summary>
    ///     将string转换为DateTime，若转换失败，则返回日期最小值。不抛出异常。
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static DateTime ParseToDateTime(this string str)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                return DateTime.MinValue;
            }

            if (str.Contains('-') || str.Contains('/'))
            {
                return DateTime.Parse(str);
            }

            var length = str.Length;
            return length switch
            {
                4 => DateTime.ParseExact(str, "yyyy", CultureInfo.CurrentCulture),
                6 => DateTime.ParseExact(str, "yyyyMM", CultureInfo.CurrentCulture),
                8 => DateTime.ParseExact(str, "yyyyMMdd", CultureInfo.CurrentCulture),
                10 => DateTime.ParseExact(str, "yyyyMMddHH", CultureInfo.CurrentCulture),
                12 => DateTime.ParseExact(str, "yyyyMMddHHmm", CultureInfo.CurrentCulture),
                _ => DateTime.ParseExact(str, "yyyyMMddHHmmss", CultureInfo.CurrentCulture)
            };
        }
        catch
        {
            return DateTime.MinValue;
        }
    }

    /// <summary>
    ///     将string转换为DateTime，若转换失败，则返回默认值。
    /// </summary>
    /// <param name="str"></param>
    /// <param name="defaultValue"></param>
    /// <returns></returns>
    public static DateTime ParseToDateTime(this string str, DateTime? defaultValue)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                return defaultValue.GetValueOrDefault();
            }

            if (str.Contains('-') || str.Contains('/'))
            {
                return DateTime.Parse(str);
            }

            var length = str.Length;
            return length switch
            {
                4 => DateTime.ParseExact(str, "yyyy", CultureInfo.CurrentCulture),
                6 => DateTime.ParseExact(str, "yyyyMM", CultureInfo.CurrentCulture),
                8 => DateTime.ParseExact(str, "yyyyMMdd", CultureInfo.CurrentCulture),
                10 => DateTime.ParseExact(str, "yyyyMMddHH", CultureInfo.CurrentCulture),
                12 => DateTime.ParseExact(str, "yyyyMMddHHmm", CultureInfo.CurrentCulture),
                _ => DateTime.ParseExact(str, "yyyyMMddHHmmss", CultureInfo.CurrentCulture)
            };
        }
        catch
        {
            return defaultValue.GetValueOrDefault();
        }
    }

    #endregion
}